
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;

namespace Swaf.Gui.AspNet2
{
	[Themeable(true)]
	[ParseChildren(false)]
	public class DivLayers : System.Web.UI.Control
	{
		protected string m_numLayers = "0";
		protected string m_cssClass = "DivLayers";
		protected string m_width = null;
		protected BoxTypes m_type = BoxTypes.divs;
		protected string m_baseImageName = null;
		protected string m_innerMargins = null;
		protected string m_innerPadding = null;
		protected string m_sections = null;
		protected string m_resizable = null;
		protected int m_minWidth = 0, m_minHeight = 0;
		protected int m_mainMinWidth = 0, m_mainMinHeight = 0;
		protected bool m_allowResizable = false;

		public enum BoxTypes { divs, fullPngTable, cornersPngTable }

		[Category("Appearance")]
		public BoxTypes BoxType { get { return m_type; } set { m_type = value; } }

		[Category("Appearance")]
		public string Width { get { return m_width; } set { m_width = value; } }

		[Category("Appearance")]
		public string NumLayers { get { return m_numLayers; } set { m_numLayers = value; } }

		[Category("Appearance")]
		public string CssClass { get { return m_cssClass; } set { m_cssClass = value; } }



		[Category("Appearance")]
		public string Sections { get { return m_sections; } set { m_sections = value; } }

		[Category("Appearance")]
		public string Resizable { get { return m_resizable; } set { m_resizable = value; } }

		[Category("Appearance")]
		public int MainMinWidth { get { return m_mainMinWidth; } set { m_mainMinWidth = value; } }

		[Category("Appearance")]
		public int MainMinHeight { get { return m_mainMinHeight; } set { m_mainMinHeight = value; } }

		[Category("Appearance")]
		public bool AllowResizable { get { return m_allowResizable; } set { m_allowResizable = value; } }
		

		/// <summary>
		/// Only used when BoxType is BoxTypes.pngTable
		/// </summary>
		[Category("Appearance")]
		public string BaseImageName { get { return m_baseImageName; } set { m_baseImageName = value; } }

		/// <summary>
		/// Only used when BoxType is BoxTypes.pngTable
		/// </summary>
		[Category("Appearance")]
		public string InnerMargins { get { return m_innerMargins; } set { m_innerMargins = value; } }

		/// <summary>
		/// Only used when BoxType is BoxTypes.pngTable
		/// </summary>
		[Category("Appearance")]
		public string InnerPadding { get { return m_innerPadding; } set { m_innerPadding = value; } }

		protected override void Render(HtmlTextWriter writer)
		{
			if (BoxType == BoxTypes.divs)
				renderAsDivs(writer);
			else if (BoxType == BoxTypes.fullPngTable || BoxType == BoxTypes.cornersPngTable)
				renderAsPngTable(writer, BoxType);
		}

		protected virtual void renderAsPngTable(HtmlTextWriter writer, BoxTypes type)
		{
			string cssClass = "";
			if (!Cmn.IsEmpty(CssClass))
				cssClass = string.Format(" class='{0}'", CssClass);
			if(Cmn.IsEmpty(Width))
				writer.Write("<table id='{0}' cellpadding=\"0\" cellspacing=\"0\"{1}>", ClientID, cssClass);
			else
				writer.Write("<table id='{0}' cellpadding=\"0\" cellspacing=\"0\" style=\"width:{1};\"{2}>", ClientID, Width, cssClass);
			writer.Write("<tr style='line-height:0px'><td style='vertical-align:bottom'><img src=\"{0}TL.png\" /></td>", BaseImageName);
			writer.Write("<td style='background:url({0}{1}M.png) repeat-x bottom;\'></td>", BaseImageName, type==BoxTypes.fullPngTable?"T":"");
			writer.Write("<td style='vertical-align:bottom'><img src=\"{0}TR.png\" /></td></tr>", BaseImageName);

			writer.Write("<tr><td style=\"background:url({0}M{1}.png) repeat-y left;\"></td>", BaseImageName, type == BoxTypes.fullPngTable ? "L" : "");
			writer.Write("<td style=\"background:url({0}MM.png) repeat;\">", BaseImageName);
			writer.Write("<div id='{0}{1}Cnt' style=\"margin:{2};position:relative;z-index:2;padding:{3}\">",
				ClientID, ClientIDSeparator, InnerMargins, InnerPadding);

			RenderChildren(writer);

			writer.Write("</div></td>");
			writer.Write("<td style=\"background:url({0}M{1}.png) repeat-y right;\"></td></tr>", BaseImageName, type == BoxTypes.fullPngTable ? "R" : "");

			writer.Write("<tr style='line-height:0px'><td valign='top'><img src=\"{0}BL.png\" /></td>", BaseImageName);
			writer.Write("<td valign='top' style=\"background:url({0}{1}M.png) repeat-x top;\"></td>", BaseImageName, type == BoxTypes.fullPngTable ? "B" : "");
			writer.Write("<td valign='top'><img src=\"{0}BR.png\" /></td>", BaseImageName);
			writer.Write("</tr></table>");
			renderResizable(writer);
		}

		protected virtual void renderAsDivs(HtmlTextWriter writer)
		{
			int numLayers = 0;
			int.TryParse(Swaf.Application.currentApp.resMgr.resolve(NumLayers), out numLayers);
			int actualLayers = numLayers;

			string cssClass = Cmn.IsEmpty(m_cssClass) ? null : Swaf.Application.currentApp.resMgr.resolve(m_cssClass);
			if (!Cmn.IsEmpty(cssClass))
			{
				writer.Write("<div id='{0}{1}Outer' class='{2}'>", ClientID, ClientIDSeparator, cssClass);
				actualLayers++;
			}
			char p = 'a';
			for (int pos = 0; pos < numLayers - 1; pos++)
				writer.Write("<div class='{0}{1}'>", cssClass, (char)(p + pos));
			if (numLayers > 0)
			{
				writer.Write("<div id='{0}{1}Cnt' class='{2}-c' >", ClientID, ClientIDSeparator, cssClass);
				writer.Write("<div class='{0}-w'></div>", cssClass);
			}

			RenderChildren(writer);

			for (int pos = 0; pos < actualLayers; pos++)
				writer.Write("</div>");

			renderResizable(writer);
		}

		protected void renderResizable(HtmlTextWriter writer)
		{
			if (AllowResizable && !Cmn.IsEmpty(Resizable))
			{
				string res = Resizable;
				res = res.Replace("$clientId$",ClientID + ClientIDSeparator)
					.Replace("$mainMinWidth$", MainMinWidth.ToString()).Replace("$mainMinHeight$", MainMinHeight.ToString());
				writer.Write("<script>$(\"#{0}_Cnt\").resizable({1});</script>",
					ClientID, res);
			}
		}

		protected override void RenderChildren(HtmlTextWriter writer)
		{
			IDictionary sectionInfo = null;
			if (!Cmn.IsEmpty(Sections))
			{
				sectionInfo = Json.JsonMapper.ToObject(Sections);

				List<Control> rendered = new List<Control>();
				foreach (DictionaryEntry section in sectionInfo)
				{
					foreach (Control childCtl in Controls)
					{
						string cid = null;
						HtmlControl c = null;
						if (childCtl is HtmlControl)
						{
							c = (HtmlControl)childCtl;
							cid = c.Attributes["cid"];
						}
						if (cid != null && cid.CompareTo(section.Key) == 0)
						{
							if (c != null)
								c.Attributes.Add("style", c.Attributes["style"] + sectionInfo[cid].ToString());
							childCtl.ID = cid;
							childCtl.RenderControl(writer);
							rendered.Add(childCtl);

							break;
						}
					}
				}
				foreach (Control ctl in Controls)
					if (!rendered.Contains(ctl))
						ctl.RenderControl(writer);
			}
			else
			{
				foreach (Control childCtl in Controls)
					childCtl.RenderControl(writer);
			}
		}
	}

}
